package cd.zhixuan.utils.task;

import androidx.annotation.IntRange;
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;

import cd.zhixuan.utils.ObjectTools;


/**
 * 在超时时间内，拼接字节流，找到头尾后返回数据
 *
 * @author: HuZC
 * @Description: 解决接收到的字节流可能不连贯问题
 * @Date: 2022/1/11
 */
public class ReadByteHeadTailAdapter extends ReadByteAdapterAbs {
    /**
     * 报头 NULL：从头开始返回
     */
    @Nullable
    public final byte[] head;
    /**
     * 报尾 NULL：尽快返回值
     */
    @Nullable
    public final byte[] tail;

    public ReadByteHeadTailAdapter(@NonNull OnCallBack callBack) {
        this(100, callBack);
    }

    public ReadByteHeadTailAdapter(int timeout, @NonNull OnCallBack callBack) {
        this(null, null, timeout, callBack);
    }

    public ReadByteHeadTailAdapter(@Nullable byte[] head, @Nullable byte[] tail, @IntRange(from = 0, to = Integer.MAX_VALUE) int timeout,
                                   @NonNull OnCallBack callBack) {
        super(timeout, callBack);
        this.head = head;
        this.tail = tail;
    }

    public void read(@NonNull final byte[] BUFFER) {
        super.read(BUFFER, BUFFER.length);
    }

    @Override
    public void read(@NonNull byte[] BUFFER, int length) {
        if (checkTimeout()) {
            //判断超时
        }
        if (length == 0) {
            return;
        }
        if (data == null) {
            setState(State.READING);
            timestart = System.currentTimeMillis();
            data = new byte[length];
            System.arraycopy(BUFFER, 0, data, 0, length);
        } else {
            byte[] temp = data;
            data = new byte[temp.length + length];
            System.arraycopy(temp, 0, data, 0, temp.length);
            System.arraycopy(BUFFER, 0, data, temp.length, length);
        }
        checkSelf();
    }

    /**
     * 检查报头报尾
     */
    private void checkSelf() {
        if (data == null) return;
        boolean findHead = true;
        boolean findTail = true;
        byte[] headTail;
        if (head != null && head.length > 0) {
            //对报头有要求
            headTail = ObjectTools.findHeadTail(data, head, true);
            findHead = headTail != null;
            if (findHead) {
                data = headTail;
            }
        }
        if (findHead) {
            if (tail != null && tail.length > 0) {
                //对报尾有要求
                headTail = ObjectTools.findHeadTail(data, tail, false);
                findTail = headTail != null;
                if (findTail) {
                    data = headTail;
                }
            }
        }

        if (findHead && findTail) {
            if (data != null && data.length > 0) {
                notifyCallbackRead(data, System.currentTimeMillis() - timestart);
                setState(State.FINISHED);
                clear();
            }
        }
    }

}
